<template>
  <q-form ref="formRef" @submit="handleSubmit" @validation-error="handleFailed">
    <template v-for="field in fields" :key="field.field">
      <!-- 输入框 -->
      <q-input
        v-if="field.type === 'input'"
        v-model="modelValue[field.field]"
        :label="field.label"
        :rules="field.rules"
        :dense="field.dense"
        v-bind="field.props"
        @update:model-value="updateField(field.field, $event)"
      />

      <!-- 选择器 -->
      <q-select
        v-else-if="field.type === 'select'"
        v-model="modelValue[field.field]"
        :options="field.options"
        :label="field.label"
        :rules="field.rules"
        :dense="field.dense"
        v-bind="field.props"
        @update:model-value="updateField(field.field, $event)"
      />

      <template v-if="field.type === 'date'">
        <q-input
          v-model="modelValue[field.field]"
          :label="field.label"
          :rules="field.rules"
          :dense="field.dense"
          v-bind="field.props"
          readonly
        >
          <template v-slot:prepend>
            <q-icon name="event" class="cursor-pointer">
              <q-popup-proxy cover transition-show="scale" transition-hide="scale">
                <q-date
                  v-model="modelValue[field.field]"
                  mask="YYYY-MM-DD"
                  @update:model-value="updateField(field.field, $event)"
                >
                  <div class="row items-center justify-end">
                    <q-btn v-close-popup label="Close" color="primary" flat />
                  </div>
                </q-date>
              </q-popup-proxy>
            </q-icon>
          </template>
        </q-input>
      </template>

      <!-- 时间选择器 -->
      <template v-else-if="field.type === 'time'">
        <q-input
          v-model="modelValue[field.field]"
          :label="field.label"
          :rules="field.rules"
          :dense="field.dense"
          v-bind="field.props"
          readonly
        >
          <template v-slot:prepend>
            <q-icon name="access_time" class="cursor-pointer">
              <q-popup-proxy cover transition-show="scale" transition-hide="scale">
                <q-time
                  v-model="modelValue[field.field]"
                  mask="HH:mm"
                  format24h
                  @update:model-value="updateField(field.field, $event)"
                >
                  <div class="row items-center justify-end">
                    <q-btn v-close-popup label="Close" color="primary" flat />
                  </div>
                </q-time>
              </q-popup-proxy>
            </q-icon>
          </template>
        </q-input>
      </template>

      <!-- 日期时间选择器 -->
      <template v-else-if="field.type === 'datetime'">
        <q-input
          v-model="modelValue[field.field]"
          :label="field.label"
          :rules="field.rules"
          :dense="field.dense"
          v-bind="field.props"
          readonly
        >
          <template v-slot:prepend>
            <q-icon name="event" class="cursor-pointer">
              <q-popup-proxy cover transition-show="scale" transition-hide="scale">
                <q-date
                  v-model="modelValue[field.field]"
                  mask="YYYY-MM-DD"
                  @update:model-value="updateField(field.field, $event)"
                >
                  <div class="row items-center justify-end">
                    <q-btn v-close-popup label="Close" color="primary" flat />
                  </div>
                </q-date>
              </q-popup-proxy>
            </q-icon>
          </template>
          <template v-slot:append>
            <q-icon name="access_time" class="cursor-pointer">
              <q-popup-proxy cover transition-show="scale" transition-hide="scale">
                <q-time
                  v-model="modelValue[field.field]"
                  mask="HH:mm"
                  format24h
                  @update:model-value="updateField(field.field, $event)"
                >
                  <div class="row items-center justify-end">
                    <q-btn v-close-popup label="Close" color="primary" flat />
                  </div>
                </q-time>
              </q-popup-proxy>
            </q-icon>
          </template>
        </q-input>
      </template>

      <!-- 单选框组 -->
      <q-option-group
        v-else-if="field.type === 'radio'"
        v-model="modelValue[field.field]"
        :options="field.options"
        type="radio"
        :label="field.label"
        :rules="field.rules"
        :dense="field.dense"
        v-bind="field.props"
        @update:model-value="updateField(field.field, $event)"
      />

      <!-- 复选框组 -->
      <q-option-group
        v-else-if="field.type === 'checkbox'"
        v-model="modelValue[field.field]"
        :options="field.options"
        type="checkbox"
        :label="field.label"
        :rules="field.rules"
        :dense="field.dense"
        v-bind="field.props"
        @update:model-value="updateField(field.field, $event)"
      />
    </template>
  </q-form>
</template>

<script setup>
import { ref } from 'vue'
import { QForm, QInput, QSelect, QDate, QTime, QOptionGroup } from 'quasar'

const modelValue = defineModel('modelValue')
defineProps({
  fields: {
    type: Array,
    default: () => [],
  },
})

const emit = defineEmits(['update:modelValue', 'submit', 'failed'])

const updateField = (field, value) => {
  emit('update:modelValue', {
    ...modelValue.value,
    [field]: value,
  })
}

const formRef = ref(null)

const validate = () => {
  return formRef.value?.validate()
}

const resetFields = () => {
  formRef.value?.resetValidation()
}

const handleSubmit = (values) => {
  emit('submit', values)
}

const handleFailed = (errorInfo) => {
  emit('failed', errorInfo)
}

defineExpose({
  validate,
  resetFields,
  formRef,
})
</script>

<style scoped>
.q-pa-md {
  padding: 16px;
}
</style>
